home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / lists / dl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  42.4 KB  |  1,920 lines

  1. /* dl.c: */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/lists/RCS/dl.c,v 6.0 1991/12/18 20:10:43 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/lists/RCS/dl.c,v 6.0 1991/12/18 20:10:43 jpo Rel $
  9.  *
  10.  * $Log: dl.c,v $
  11.  * Revision 6.0  1991/12/18  20:10:43  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "dlist.h"
  19. #include "retcode.h"
  20. #include <isode/quipu/ds_search.h>
  21. #include <isode/quipu/connection.h>    /* ds_search uses di_block - include this for lint !!! */
  22. #include <isode/quipu/dua.h>
  23. #include <varargs.h>
  24. #include <isode/tailor.h>
  25. #include "dl.h"
  26.  
  27. extern LLog    *log_dsap;
  28. extern char * tailfile;
  29. extern char * dsa_address;
  30. extern char * myname;
  31. extern char * local_dit;
  32. extern char *postmaster;
  33. extern Attr_Sequence current_print;
  34. extern AttributeType at_Member;
  35. extern AttributeType at_ObjectClass;
  36. extern AttributeType at_Permit;
  37. extern AttributeType at_Policy;
  38. extern char * dn2str();
  39. extern char * dn2ufn();
  40.  
  41. extern Filter strfilter(), ocfilter(), joinfilter();
  42.  
  43. DN localdn = NULLDN;
  44. DN user = NULLDN;
  45. extern int str2dl();
  46. DN get_manager_dn();
  47. DN mail2dn();
  48. DN dl_str2ufn ();
  49. char * userstr;
  50. char * strdl = NULLCP;
  51. char manager_mode = FALSE;
  52. char verify = FALSE;
  53. char quiet = FALSE;
  54. char printdl = FALSE;
  55. Attr_Sequence ufn_dl;
  56.  
  57. ORName * ufn_orName_parse();
  58. extern OR_ptr orAddr_parse_user();
  59.  
  60. char * pager;
  61. FILE * out;
  62.  
  63. ORName * user_in_list ();
  64. ORName * addr_in_list ();
  65.  
  66. main (argc, argv)
  67. int    argc;
  68. char    **argv;
  69. {
  70. DN dn_dl = NULLDN;
  71. int n = 1;
  72.     sys_init(argv[0]);
  73.  
  74.     quipu_syntaxes ();
  75.  
  76.     pp_syntaxes ();
  77.     or_myinit();
  78.  
  79.     dsap_init (&n, &argv);
  80.     log_dsap -> ll_file = strdup ("dsap.log");
  81.  
  82.     (void) pp_quipu_run ();
  83.  
  84.     if ((pager = getenv("PAGER")) == NULL)
  85.         pager = "more";
  86.  
  87.     if (local_dit)
  88.         localdn = str2dn (local_dit);
  89.     
  90.     do_args (argc,argv, &dn_dl);
  91.  
  92.     if (dn_dl)
  93.           do_list (dn_dl,strdl);
  94.     else    
  95.           do_select ();
  96.  
  97.     dl_unbind ();
  98. }
  99.  
  100. do_args (argc,argv,dn_dl)
  101. int     argc;
  102. char    **argv;
  103. DN    *dn_dl;
  104. {
  105. int x, res;
  106. char * dsa = NULLCP;
  107. char * passwd = NULLCP;
  108. char buf [LINESIZE];
  109.  
  110.     for (x=1; x<argc; x++) {
  111.         if (strcmp (argv[x], "-u") == 0) {
  112.              if (++x == argc) {
  113.                 (void) fprintf (stderr,"user name missing\n");
  114.                 exit (-1);
  115.              }
  116.              userstr = argv[x];
  117.              if ((user = str2dn (argv[x])) == NULLDN) {
  118.                 (void) fprintf (stderr,"Error in DN '%s'\n",argv[x]);
  119.                 exit (-1);
  120.              }
  121.           } else if (strcmp(argv[x], "-c") == 0) {
  122.              if (++x == argc) {
  123.                 (void) fprintf (stderr,"dsa name missing\n");
  124.                 exit (-1);
  125.              }
  126.              dsa = argv[x];
  127.           } else if (strcmp(argv[x], "-m") == 0) {
  128.              manager_mode = TRUE;
  129.           } else if (strcmp(argv[x], "-q") == 0) {
  130.              quiet = TRUE;
  131.           } else if (strcmp(argv[x], "-p") == 0) {
  132.              printdl = TRUE;
  133.           } else if (strcmp(argv[x], "-v") == 0) {
  134.              verify = TRUE;
  135.           } else if (*argv[x] == '-') {
  136.              (void) fprintf (stderr,"Usage: %s [-u <DN>] [-c <dsa>] [listname] -m -q -v -p\n",argv[0]);
  137.              exit (-1);
  138.           } else
  139.              strdl = argv[x];
  140.     }
  141.  
  142.     if (printdl && !strdl) {
  143.         (void) fprintf (stderr,"print which list ?\n");
  144.         exit (-1);
  145.         }
  146.  
  147.     if (dsa != NULLCP) {
  148.           FILE    *fp;
  149.           char    save_bdsa[LINESIZE];
  150.           
  151.         (void) strcpy (myname = save_bdsa, dsa);
  152.           dsa_address = NULLCP;
  153.  
  154.           /* read tailor file to get address */
  155.           
  156.           if( (fp = fopen(isodefile(tailfile, 0), "r")) == (FILE *)NULL) {
  157.              (void) fprintf (stderr,"can't open %s",tailfile);
  158.              exit (-1);
  159.           }
  160.  
  161.           while(fgets(buf, sizeof(buf), fp) != NULLCP)
  162.              if ( (*buf != '#') && (*buf != '\n') )
  163.                 /* not a comment or blank */
  164.                 (void) tai_string (buf);
  165.  
  166.           (void) fclose(fp);
  167.           
  168.           if (dsa_address == NULLCP)
  169.              dsa_address = myname;
  170.     }
  171.  
  172.     if (user == NULLDN) {
  173.         /* try ~/.quipurc */
  174.  
  175.         FILE * file;    
  176.         char * home, *p, *part1, *part2, *TidyString();
  177.         char Dish_Home[LINESIZE];
  178.         char Read_in_Stuff[LINESIZE];
  179.         
  180.         if (home = getenv ("QUIPURC"))
  181.             (void) strcpy (Dish_Home, home);
  182.         else
  183.             if (home = getenv ("HOME"))
  184.             (void) sprintf (Dish_Home, "%s/.quipurc", home);
  185.             else
  186.             (void) strcpy (Dish_Home, "./.quipurc");
  187.  
  188.         if ((file = fopen (Dish_Home, "r")) != 0) {
  189.            while (fgets (Read_in_Stuff, LINESIZE, file) != 0) {
  190.             p = SkipSpace (Read_in_Stuff);
  191.             if (( *p == '#') || (*p == '\0'))
  192.                 continue;  /* ignore comments and blanks */
  193.             
  194.             part1 = p;
  195.             if ((part2 = index (p,':')) == NULLCP) 
  196.                 continue;
  197.         
  198.             *part2++ = '\0';
  199.             part2 = TidyString (part2);
  200.  
  201.             if (lexequ (part1, "username") == 0) {
  202.                 userstr = strdup (part2);
  203.                 user = str2dn (userstr);
  204.             } else if (lexequ (part1, "password") == 0) 
  205.                 passwd = strdup (part2);
  206.            }
  207.            (void) fclose (file);
  208.         }
  209.     }
  210.  
  211.     if ((user != NULLDN) && (passwd == NULLCP)) {
  212.           (void) sprintf (buf,"Enter password for \"%s\": ",userstr);
  213.           (void) strcpy (buf,getpassword (buf));
  214.           passwd = buf;
  215.           
  216.     }
  217.  
  218.     if (dl_bind (user,passwd) == NOTOK) {
  219.           (void) fprintf (stderr,"Attempt to connect to DSA failed\n");
  220.           exit (-1);
  221.     }
  222.  
  223.     if (strdl)
  224.             if ((res = str2dl (strdl,localdn, dn_dl)) != OK) {
  225.            if (res == NOTOK)
  226.             (void) fprintf (stderr,"Unknown list '%s'\n",strdl);
  227.            else 
  228.             (void) fprintf (stderr,"Temporary failure for '%s'\n",strdl);
  229.            exit (-1);
  230.         }
  231. }
  232.  
  233. static void openpager(ps)
  234. PS ps;
  235. {
  236.     (void) ps_flush (ps);
  237.  
  238.     if (isatty(fileno((FILE *)ps->ps_addr)) == 0) {
  239.         out = stdout;
  240.     } else if ((out = popen(pager,"w")) == NULL) {
  241.         (void) fprintf(stderr,"unable to start pager '%s'",pager);
  242.         out = stdout;
  243.     }
  244.  
  245.     ps->ps_addr = (caddr_t) out;
  246. }    
  247.  
  248. static void closepager(ps)
  249. PS ps;
  250. {
  251.     (void) ps_flush(ps);
  252.     
  253.     if (out != stdout) {
  254.         (void) pclose(out);
  255.         out = stdout;
  256.     }
  257.  
  258.     ps->ps_addr = (caddr_t) out;
  259. }
  260.  
  261. do_select ()
  262. {
  263. int    quit = FALSE;
  264. char    buf[BUFSIZ],
  265.     tmpbuf[BUFSIZ],
  266.     ch;
  267. PS    ps;
  268. DN    dn_dl;
  269. DN     newloc;
  270. int     res;
  271.  
  272.     if ((ps = ps_alloc (std_open)) == NULLPS) {
  273.           (void) fprintf (stderr,"Can't set up output (3)\n");
  274.           return;
  275.     }
  276.     if (std_setup (ps, stdout) == NOTOK) {
  277.           (void) fprintf (stderr,"Can't set up output (4)\n");
  278.           return;
  279.     }
  280.  
  281.     if (verify) {
  282.         select_all (ps);
  283.         return;
  284.     }
  285.     
  286.     while (quit == FALSE) {
  287.           (void) printf("\n> ");
  288.           (void) fflush (stdout);
  289.           if (gets (buf) == NULL) {
  290.              (void) printf ("\n");
  291.              exit(OK);
  292.           }
  293.           compress (buf, buf);
  294.           if (buf[0] == NULL || strlen(buf) == 0) {
  295.              (void) printf("\nType 'h' or '?' for help\n");
  296.              continue;
  297.           }
  298.           if ((int)strlen(buf) > 1)
  299.              ch = 'A';
  300.           else if (*buf == '?')
  301.              ch = '?';
  302.           else
  303.              ch = uptolow(*buf);
  304.           switch (ch)
  305.           {
  306.           case 'h':
  307.           case '?':
  308.              (void) printf ("\nOptions are:\n");
  309.              (void) printf ("  'l'ist the list,\n");
  310.              (void) printf ("  'c'reate a list,\n");
  311.              (void) printf ("  'u'pgrade a list to a directory list,\n");
  312.              (void) printf ("  'w'hich lists am I on,\n");
  313.              (void) printf ("  'm'ove to somewhere else in the DIT,\n");
  314.              (void) printf ("  'q'uit,\n");
  315.              (void) printf ("  OR, the name of a list to visit.\n");
  316.              break;
  317.           case 'q':
  318.              quit = TRUE;
  319.              break;
  320.           case 'l':
  321.              openpager(ps);
  322.              dl_search (ps);
  323.              closepager(ps);
  324.              break;
  325.           case 'c':
  326.              if (!user)
  327.             (void) fprintf (stderr,"Don't know your distinguished name !\n");
  328.              else if (dl_create (ps) == 0)
  329.             (void) printf ("Done\n");
  330.              else
  331.             (void) fprintf (stderr,"\nList creation failed\n");
  332.              break;
  333.           case 'u':
  334.              if (!user)
  335.             (void) fprintf (stderr,"Don't know your distinguished name !\n");
  336.              else if (dl_upgrade (ps) == 0)
  337.             (void) printf ("Done\n");
  338.              else
  339.             (void) fprintf (stderr,"\nList upgrade failed\n");
  340.              break;
  341.           case 'w':
  342.              openpager(ps);
  343.              which_list (ps);
  344.              closepager(ps);
  345.              continue;
  346.           case 'm':
  347.              ps_print (ps,"Currently at '");
  348.              ufn_dn_print (ps,localdn,FALSE);
  349.              ps_print (ps,"'\nEnter new location: ");
  350.              (void) ps_flush (ps);
  351.              if ((gets(tmpbuf) == NULL) || (tmpbuf == NULLCP) || (*tmpbuf == 0)) {
  352.                 ps_print (ps,"\n(exit)\n");
  353.                 clearerr(stdin);
  354.                 break;
  355.              }
  356.              compress (tmpbuf, tmpbuf);
  357.              if ((newloc = dl_str2ufn (tmpbuf)) != NULLDN) {
  358.             (void) printf ("Moved!\n");
  359.             localdn = newloc;
  360.              }
  361.                   break;
  362.           case 'A':
  363.               if ((res = str2dl (buf,localdn,&dn_dl)) == OK) {
  364.                  (void) fprintf (stderr,"Reading '%s'...\n",buf);
  365.                  do_list (dn_dl,buf);
  366.               } else {
  367.                   if (res == NOTOK)
  368.                      (void) fprintf (stderr,"Unknown list '%s'\n",buf);
  369.                   else 
  370.                      (void) fprintf (stderr,"Temporary failure '%s'\n",buf);
  371.               }
  372.               break;
  373.           default:
  374.              (void) printf("\nType 'h' or '?' for help\n");
  375.              break;
  376.           }
  377.     }
  378.     ps_free (ps);
  379. }
  380.  
  381. static ORName * num2or (num)
  382. int num;
  383. {
  384. Attr_Sequence as;
  385. AV_Sequence avs;
  386. int i = 1;
  387.  
  388.     if (current_print == NULLATTR) {
  389.         (void) fprintf (stderr,"List has changed - check number!!!\n");
  390.         return NULLORName;    
  391.     }
  392.  
  393.     if ((as = as_find_type (current_print,at_Member)) == NULLATTR) {
  394.         (void) fprintf (stderr,"List has changed - check number!!!\n");
  395.         return NULLORName;    
  396.     }
  397.  
  398.     for(avs = as->attr_value; avs != NULLAV; avs = avs->avseq_next, i++) 
  399.         if (i == num) {
  400.             current_print = NULLATTR;
  401.             return (ORName *) avs->avseq_av.av_struct;
  402.         }
  403.  
  404.     (void) fprintf (stderr,"Number too high\n");
  405.     return NULLORName;
  406.     
  407. }
  408.  
  409. do_list (dn_dl,prompt)
  410. DN dn_dl;
  411. char * prompt;
  412. {
  413. Attr_Sequence as;
  414. int    quit = FALSE;
  415. char    buf[BUFSIZ],
  416.     tmpbuf[BUFSIZ],
  417.     ch;
  418. PS    ps;
  419. ORName * orname;
  420. char     can_write;
  421. ORName * on_list;
  422. char    re_read = FALSE;
  423.  
  424.     switch (dir_getdl_aux (dn_dl, &as)) {
  425.         case OK:
  426.         break;
  427.         case DONE:
  428.         (void) fprintf (stderr, "Temporary failure to read the list '%s'\n",dn2ufn(dn_dl,FALSE));
  429.         return;
  430.         default:
  431.         (void) fprintf (stderr,"Can't read the list '%s'\n",dn2ufn(dn_dl,FALSE));
  432.         return;
  433.     }
  434.  
  435.     if ((ps = ps_alloc (std_open)) == NULLPS) {
  436.           (void) fprintf (stderr,"Can't set up output\n");
  437.           return;
  438.     }
  439.     if (std_setup (ps, stdout) == NOTOK) {
  440.            (void)fprintf (stderr,"Can't set up output (2)\n");
  441.           return;
  442.     }
  443.  
  444.     if (printdl) {
  445.          dl_print (ps,dn_dl);
  446.          return;
  447.     }
  448.     
  449.     if (verify) {
  450.         if (manager_mode)
  451.             check_dl_members (ps,dn_dl,as,TRUE,TRUE,TRUE,quiet);
  452.         else
  453.             check_dl_members (ps,dn_dl,as,TRUE,TRUE,FALSE,quiet);
  454.         return;
  455.     }
  456.  
  457.     if (!(can_write = can_user_write (as,user))) {
  458.         if (!quiet)
  459.            (void) printf("Only the manager can modify this list.\n");
  460.         on_list = user_in_list (as,user);
  461.     }
  462.  
  463.  
  464.     while (quit == FALSE) {
  465.  
  466.         if (re_read) {
  467.             switch (dir_getdl_aux (dn_dl, &as)){
  468.                 case OK:
  469.                 break;
  470.                 case DONE:
  471.                 (void) fprintf (stderr, "Temporary failure to re-read the list\n");
  472.                 return;
  473.                 default:
  474.                 (void) fprintf (stderr,"Can't re-read the list!\n");
  475.                 return;
  476.             }
  477.             if (!(can_write = can_user_write (as,user)))
  478.                 on_list = user_in_list (as,user);
  479.  
  480.             re_read = FALSE;
  481.         }
  482.  
  483.           (void) printf("\n%s> ",prompt);
  484.           (void) fflush (stdout);
  485.           if (gets (buf) == NULL) {
  486.              clearerr (stdin);
  487.              (void) printf("\n");
  488.              return;
  489.           }
  490.           compress (buf, buf);
  491.           if (buf[0] == NULL || strlen(buf) == 0) {
  492.              (void) printf("\nType 'h' or '?' for help\n");
  493.              continue;
  494.           }
  495.           if ((int)strlen(buf) > 1)
  496.              ch = 'Z';
  497.           else if (*buf == '?')
  498.              ch = '?';
  499.           else
  500.              ch = uptolow(*buf);
  501.           switch (ch)
  502.           {
  503.           case 'h':
  504.           case '?':
  505.              (void) printf ("\nOptions are:\n");
  506.              (void) printf ("  'p'rint to view the list,\n");
  507.              (void) printf ("  'f'ind entry in the list\n");
  508.              (void) printf ("  'c'heck the list, reporting errors,\n");
  509.              if (can_write) {
  510.                  (void) printf ("  'v'alidate the list, updating errors,\n");
  511.                  (void) printf ("  'r'emove an entry from the list,\n");
  512.                  (void) printf ("  'm'odify attributes (owner, policy and permission),\n");
  513.                  (void) printf ("  'q'uit,\n");
  514.                  (void) printf ("  OR, enter an ORName to add to the list.\n");
  515.              } else {
  516.                  if (on_list) 
  517.                      (void) printf ("  'r'emove yourself from the list,\n");
  518.                  else if (user)
  519.                      (void) printf ("  'a'dd yourself to the list,\n");
  520.                  (void) printf ("  'q'uit.\n");
  521.              }
  522.              break;
  523.           case 'q':
  524.              quit = TRUE;
  525.              break;
  526.           case 'p':
  527.              openpager(ps);
  528.              dl_print (ps,dn_dl);
  529.              closepager(ps);
  530.              break;
  531.           case 'f':
  532.              (void) printf ("give name to check: ");
  533.              if ((gets(tmpbuf) == NULL) || (tmpbuf == NULLCP) || (*tmpbuf == 0)) {
  534.                 ps_print (ps,"\n(exit)\n");
  535.                 clearerr(stdin);
  536.                 break;
  537.              }
  538.              compress (tmpbuf, tmpbuf);
  539.              orname = ufn_orName_parse (tmpbuf,as);
  540.  
  541.              if (orname != NULLORName) {
  542.                 ps_print (ps,"Found: ");
  543.                 orName_print (ps,orname,UFNOUT);
  544.              }
  545.              break;
  546.  
  547.           case 'r':
  548.              if (! can_write) {
  549.                 if (on_list) {
  550.                     if (! user)
  551.                         goto wally;
  552.                     (void) mail_manager (ps,user,TRUE,as,dn_dl);
  553.                     break;
  554.                 } 
  555.                 goto wally;
  556.              }
  557.              (void) printf ("give username to be removed: ");
  558.              if ((gets(tmpbuf) == NULL) || (tmpbuf == NULLCP) || (*tmpbuf == 0)) {
  559.                 ps_print (ps,"\n(exit)\n");
  560.                 clearerr(stdin);
  561.                 break;
  562.              }
  563.              compress (tmpbuf, tmpbuf);
  564.              if (isdigit (*tmpbuf))
  565.             orname = num2or (atoi(tmpbuf));
  566.              else 
  567.             orname = ufn_orName_parse (tmpbuf,as);
  568.  
  569.              if (orname != NULLORName) {
  570.               if (check_list (ps,orname,as,dn_dl,TRUE)) {
  571.                  if (! orname_confirm(ps,orname,TRUE)) {
  572.                     clearerr(stdin);
  573.                     break;
  574.                  }
  575.                 ps_print (ps,"Removing...\n");
  576.                 (void) dl_modify (ps,orname,dn_dl,TRUE);
  577.                 re_read = TRUE;
  578.                   }
  579.              }
  580.              break;
  581.           case 'c':
  582.              switch (dir_getdl_aux (dn_dl, &as)) {
  583.              case OK:
  584.                  break;
  585.              case DONE:
  586.                  fprintf (stderr, "Temporary failure to read the list\n");
  587.                  break;
  588.              default:
  589.                  (void) fprintf (stderr,"Can't read the list\n");
  590.                  break;
  591.              }
  592.              openpager(ps);
  593.              check_dl_members (ps,dn_dl,as,TRUE,TRUE,FALSE,quiet);
  594.              closepager(ps);
  595.              break;
  596.           case 'v':
  597.              if (! can_write)
  598.                 goto wally;
  599.              switch (dir_getdl_aux (dn_dl, &as)) {
  600.              case OK:
  601.                  break;
  602.              case DONE:
  603.                  (void) fprintf (stderr, "Temporary failure to read the list\n");
  604.                  break;
  605.              default:
  606.                  (void) fprintf (stderr,"Can't read the list\n");
  607.                  break;
  608.              }
  609.              check_dl_members (ps,dn_dl,as,TRUE,TRUE,TRUE,quiet);
  610.              re_read = TRUE;
  611.              break;
  612.           case 'a':
  613.              if (! can_write) {
  614.             if (on_list) {
  615.                 ps_print (ps,"You are already on the list!\n");
  616.             } else {
  617.                 if (!user)
  618.                     goto wally;
  619.                 (void) mail_manager (ps,user,FALSE,as,dn_dl);
  620.             }
  621.              } else 
  622.                  (void) printf("\nType 'h' or '?' for help\n");
  623.              break;
  624.           case 'm':
  625.              if (! can_write) 
  626.                  goto wally;
  627.              else 
  628.                  modify_dl_attrs (ps,dn_dl,as);
  629.              break;
  630.           case 'Z':
  631.              if (! can_write) {
  632. wally:;
  633.             if (user) {
  634.                 ps_print (ps,"\nYou do not have sufficient access rights to modify the list,\n");
  635.                 ps_print (ps,"You should contact the list manager (");
  636.                 ufn_dn_print (ps,get_manager_dn(as,TRUE),FALSE);
  637.                 ps_print (ps,").\n");
  638.             } else {
  639.                 ps_print (ps,"\nI don't know who you are.\n");
  640.             }
  641.             break;
  642.  
  643.              } else if ((orname = ufn_orName_parse (buf,NULLATTR)) != NULLORName)
  644.                  if (check_list (ps,orname,as,dn_dl,FALSE)) {
  645.                      if (orname_confirm(ps,orname,FALSE)) {
  646.                          (void) dl_modify(ps,orname,dn_dl,FALSE);
  647.                          re_read = TRUE;
  648.                      }
  649.                  }
  650.              break;
  651.           default:
  652.              (void) printf("\nType 'h' or '?' for help\n");
  653.              break;
  654.           }
  655.     }
  656.     ps_free (ps);
  657. }
  658.  
  659. check_list (ps,orname,as,dn_dl,remove) 
  660. PS ps;
  661. ORName * orname;
  662. Attr_Sequence as;
  663. DN dn_dl;
  664. char remove;
  665. {
  666. ORName * or;
  667.  
  668.      if (orname->on_dn) 
  669.     if (or = user_in_list (as,orname->on_dn))     /* Assign */
  670.         goto out;
  671.  
  672.      if (orname->on_or) {
  673.     if (or = addr_in_list (as,orname->on_or)) {    /* Assign */
  674. out:;
  675.         if (remove) 
  676.             return TRUE;
  677.             else {
  678.             ps_print (ps,"'");
  679.             orName_print (ps,or,UFNOUT);
  680.             ps_print (ps,"' is already on the list!\n");
  681.             (void) check_ORName (ps,or,TRUE,TRUE,FALSE,dn_dl,FALSE);
  682.             return FALSE;
  683.         }
  684.     }
  685.      }
  686.  
  687.      if (remove) {
  688.         ps_print (ps,"'");
  689.         orName_print (ps,or,UFNOUT);
  690.         ps_print (ps,"' is not on the list!\n");
  691.         return FALSE;
  692.      }
  693.  
  694.      return check_ORName (ps,orname,TRUE,TRUE,FALSE,dn_dl,FALSE);
  695.  
  696. }
  697.  
  698. dl_search (ps) 
  699. PS ps;
  700. {
  701. struct ds_search_arg search_arg;
  702. static struct ds_search_result result;
  703. struct DSError err;
  704. static CommonArgs ca = default_common_args;
  705. Filter filt;
  706. EntryInfo * ptr;
  707.  
  708.     if ((filt = ocfilter ("ppDistributionList")) == NULLFILTER)
  709.         return;
  710.  
  711.     search_arg.sra_baseobject = localdn;
  712.     search_arg.sra_filter = filt;
  713.     search_arg.sra_subset = SRA_ONELEVEL;
  714.     search_arg.sra_searchaliases = FALSE;
  715.     search_arg.sra_common = ca; /* struct copy */
  716.     search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  717.     search_arg.sra_eis.eis_allattributes = FALSE;
  718.     search_arg.sra_eis.eis_select = NULLATTR;
  719.  
  720.     if (ds_search (&search_arg, &err, &result) != DS_OK) {
  721.         filter_free (filt);
  722.         log_ds_error (&err);
  723.         ds_error_free (&err);
  724.         (void) fprintf (stderr,"Search returned an error !\n");
  725.         return;
  726.     }
  727.  
  728.     ps_print (ps,"Found the following lists:");
  729.  
  730.     for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; ptr=ptr->ent_next) {
  731.         ps_print (ps,"\n  ");
  732.         ufn_dn_print (ps,ptr->ent_dn,FALSE);    
  733.     }
  734.     ps_print (ps,"\n");
  735. }
  736.  
  737.  
  738. select_all (ps)
  739. PS ps;
  740. {
  741. struct ds_search_arg search_arg;
  742. static struct ds_search_result result;
  743. struct DSError err;
  744. static CommonArgs ca = default_common_args;
  745. Filter filt;
  746. EntryInfo * ptr;
  747. int res;
  748. Attr_Sequence as;
  749. static PS nps = NULLPS;
  750.  
  751.     if (nps == NULL
  752.         && ((nps = ps_alloc (str_open)) == NULLPS)
  753.             || str_setup (nps, NULLCP, BUFSIZ, 0) == NOTOK) {
  754.     if (nps)
  755.         ps_free (nps), nps = NULLPS;
  756.  
  757.     return;
  758.     }
  759.  
  760.  
  761.     if ((filt = ocfilter ("ppDistributionList")) == NULLFILTER)
  762.         return;
  763.  
  764.     search_arg.sra_baseobject = localdn;
  765.     search_arg.sra_filter = filt;
  766.     search_arg.sra_subset = SRA_ONELEVEL;
  767.     search_arg.sra_searchaliases = FALSE;
  768.     search_arg.sra_common = ca; /* struct copy */
  769.     search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  770.     search_arg.sra_eis.eis_allattributes = FALSE;
  771.     search_arg.sra_eis.eis_select = NULLATTR;
  772.  
  773.     if (ds_search (&search_arg, &err, &result) != DS_OK) {
  774.         filter_free (filt);
  775.         log_ds_error (&err);
  776.         ds_error_free (&err);
  777.         ps_printf (ps,"Can't find any lists\n");
  778.         return;
  779.     }
  780.  
  781.     for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; ptr=ptr->ent_next) {
  782.         nps -> ps_base = NULL, nps -> ps_cnt = 0;
  783.         nps -> ps_ptr = NULL, nps -> ps_bufsiz = 0;
  784.  
  785.         switch (dir_getdl_aux (ptr->ent_dn, &as)) {
  786.             case OK:
  787.             res = check_dl_members (nps,ptr->ent_dn,as,TRUE,TRUE,FALSE,quiet);
  788.             if (res == NOTOK) {
  789.                  if (manager_mode) {
  790.                 ps_print (ps,"\nErrors found in list '");
  791.                 ufn_dn_print (ps,ptr->ent_dn,FALSE);    
  792.                 ps_print (ps,"' (manager informed).\n\n");
  793.                 *--nps -> ps_ptr = NULL, nps -> ps_cnt++;
  794.                 message2manager (ptr->ent_dn,nps->ps_base);
  795.                  } else {
  796.                 ps_print (ps,"\nErrors found in list '");
  797.                 ufn_dn_print (ps,ptr->ent_dn,FALSE);    
  798.                 *--nps -> ps_ptr = NULL, nps -> ps_cnt++;
  799.                 ps_printf (ps,"'\n%s\n\n",nps->ps_base);
  800.                  }
  801.             }
  802.             break;
  803.             case DONE:
  804.             break;
  805.             default:
  806.             ps_printf (ps,"Can't read the list '%s'\n",dn2ufn(ptr->ent_dn,FALSE));
  807.         }
  808.     }
  809. }
  810.  
  811. which_list (ps)
  812. PS ps;
  813. {
  814. struct ds_search_arg search_arg;
  815. static struct ds_search_result result;
  816. struct DSError err;
  817. static CommonArgs ca = default_common_args;
  818. Filter filt_dl, filt_dn, filt_oraddr, filt_or, filt_and, filt_dn2;
  819. EntryInfo * ptr;
  820. AttributeValue av;
  821. ORName * or, * orName_parse();
  822. OR_ptr newor, as2or(), saveor;
  823. Attr_Sequence as;
  824.  
  825.     if (user == NULLDN) {
  826.         (void) fprintf (stderr,"You did not supply a name at the start, so I don't know who you are!\n");
  827.         return;
  828.     }
  829.  
  830.     or = ufn_orName_parse (userstr,NULLATTR);
  831.     if (dn2addr (or->on_dn, &as) == OK) 
  832.         newor = as2or (as);
  833.  
  834.     if (newor == NULLOR) {
  835.         (void) fprintf (stderr,"Can't work out your mail adddress\n");
  836.         return;
  837.     }
  838.     or->on_or = newor;
  839.  
  840.     av = AttrV_alloc ();
  841.     av->av_struct = (caddr_t) or;
  842.  
  843.     av->av_syntax = at_Member->oa_syntax;
  844.  
  845.     filt_dn = filter_alloc ();
  846.     filt_dn->flt_next = NULLFILTER;
  847.     filt_dn->flt_type = FILTER_ITEM;
  848.     filt_dn->FUITEM.fi_type = FILTERITEM_EQUALITY;
  849.     filt_dn->FUITEM.UNAVA.ava_type = AttrT_cpy(at_Member);
  850.     filt_dn->FUITEM.UNAVA.ava_value = AttrV_cpy (av);
  851.  
  852.     filt_dn2 = filter_alloc ();
  853.     filt_dn2->flt_next = filt_dn;
  854.     filt_dn2->flt_type = FILTER_ITEM;
  855.     filt_dn2->FUITEM.fi_type = FILTERITEM_EQUALITY;
  856.     filt_dn2->FUITEM.UNAVA.ava_type = AttrT_cpy(at_Member);
  857.     saveor = or->on_or;
  858.     or->on_or = NULLOR;
  859.     filt_dn2->FUITEM.UNAVA.ava_value = AttrV_cpy (av);
  860.     or->on_or = saveor;
  861.  
  862.     dn_free (or->on_dn);
  863.     or->on_dn = NULLDN;
  864.  
  865.     filt_oraddr = filter_alloc ();
  866.     filt_oraddr->flt_next = filt_dn2;
  867.     filt_oraddr->flt_type = FILTER_ITEM;
  868.     filt_oraddr->FUITEM.fi_type = FILTERITEM_EQUALITY;
  869.     filt_oraddr->FUITEM.UNAVA.ava_type = AttrT_cpy(at_Member);
  870.     filt_oraddr->FUITEM.UNAVA.ava_value = av;
  871.  
  872.     filt_or = joinfilter (filt_oraddr,FILTER_OR);
  873.  
  874.     if ((filt_dl = ocfilter ("ppDistributionList")) == NULLFILTER)
  875.         return;
  876.  
  877.     filt_dl->flt_next = filt_or;
  878.  
  879.     filt_and = joinfilter (filt_dl,FILTER_AND);
  880.  
  881.     search_arg.sra_baseobject = localdn;
  882.     search_arg.sra_filter = filt_and;
  883.     search_arg.sra_subset = SRA_ONELEVEL;
  884.     search_arg.sra_searchaliases = FALSE;
  885.     search_arg.sra_common = ca; /* struct copy */
  886.     search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
  887.     search_arg.sra_eis.eis_allattributes = FALSE;
  888.     search_arg.sra_eis.eis_select = NULLATTR;
  889.  
  890.     if (ds_search (&search_arg, &err, &result) != DS_OK) {
  891.         filter_free (filt_and);
  892.         log_ds_error (&err);
  893.         ds_error_free (&err);
  894.         (void) fprintf (stderr,"Search failed\n");
  895.         return;
  896.     }
  897.     filter_free (filt_and);
  898.  
  899.     ps_print (ps,"You are on the following:");
  900.  
  901.     for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; ptr=ptr->ent_next) {
  902.         ps_print (ps,"\n  ");
  903.         ufn_dn_print (ps,ptr->ent_dn,FALSE);    
  904.     }
  905.     ps_print (ps,"\n");
  906. }
  907.  
  908. can_user_write (as,thisuser)
  909. Attr_Sequence as;
  910. DN thisuser;
  911. {
  912. DN manager;
  913.  
  914.     if (manager_mode)
  915.         return TRUE;
  916.  
  917.     if (thisuser == NULLDN)
  918.         return FALSE;
  919.  
  920.     if ((manager = get_manager_dn (as,TRUE)) == NULLDN)
  921.         return FALSE;
  922.  
  923.     if (dn_cmp (manager, thisuser) == 0)
  924.         return TRUE; 
  925.     else
  926.         return FALSE;
  927.  
  928. }
  929.  
  930. ORName * user_in_list (as,thisuser)
  931. Attr_Sequence as;
  932. DN thisuser;
  933. {
  934. ORName  * or;
  935. Attr_Sequence tmp;
  936. AV_Sequence eptr;
  937.  
  938.     if (thisuser == NULLDN)
  939.         return NULLORName;
  940.  
  941.     if ((tmp = as_find_type (as,at_Member)) == NULLATTR)
  942.         return NULLORName;
  943.  
  944.     for (eptr = tmp->attr_value; eptr != NULLAV; eptr = eptr->avseq_next) {
  945.         or = (ORName *)eptr->avseq_av.av_struct;
  946.         if (dn_cmp (or->on_dn,thisuser) == 0)
  947.             return or;
  948.     }
  949.  
  950.     return NULLORName;
  951. }
  952.  
  953.  
  954. ORName * addr_in_list (as,addr)
  955. Attr_Sequence as;
  956. OR_ptr addr;
  957. {
  958. ORName  * or;
  959. Attr_Sequence tmp;
  960. AV_Sequence eptr;
  961.  
  962.     if (addr == NULLOR)
  963.         return NULLORName;
  964.  
  965.     if ((tmp = as_find_type (as,at_Member)) == NULLATTR)
  966.         return NULLORName;
  967.  
  968.     for (eptr = tmp->attr_value; eptr != NULLAV; eptr = eptr->avseq_next) {
  969.         or = (ORName *)eptr->avseq_av.av_struct;
  970.         if (orAddr_cmp (or->on_or,addr) == 0)
  971.             return or;
  972.     }
  973.  
  974.     return NULLORName;
  975. }
  976.  
  977.  
  978. DNS dl_interact (dns,dn,s)
  979. DNS dns;
  980. DN dn;
  981. char * s;
  982. {
  983. char    buf[LINESIZE];
  984. DNS result = NULLDNS;
  985. DNS newdns;
  986. PS    ps;
  987.  
  988.     if ((ps = ps_alloc (std_open)) == NULLPS) {
  989.           (void) fprintf (stderr,"Can't set up output (5)\n");
  990.           return NULLDNS;
  991.     }
  992.     if (std_setup (ps, stdout) == NOTOK) {
  993.           (void) fprintf (stderr,"Can't set up output (6)\n");
  994.           return NULLDNS;
  995.     }
  996.     
  997.     if (dns == NULLDNS)
  998.         return NULLDNS;
  999.  
  1000.     ps_printf (ps,"Please select from the following (matching '%s'):\n",s);
  1001.     while (dns != NULLDNS) {
  1002.         ps_print (ps,"   ");
  1003.         (void) ufn_dn_print_aux (ps,dns->dns_dn,dn,TRUE);
  1004.         if (ufn_dl) {
  1005.             if (user_in_list (ufn_dl,dns->dns_dn)) {
  1006.                 DNS tmp;
  1007.                 ps_print (ps,"(Discarded - not in list)\n");
  1008.                 tmp = dns;
  1009.                 dns = dns->dns_next;
  1010.                 tmp->dns_next = NULLDNS;
  1011.                 dn_seq_free (tmp);
  1012.                 continue;
  1013.             }
  1014.         }
  1015.         ps_print (ps," [y/n] ? ");
  1016.         (void) ps_flush (ps);
  1017.  
  1018. again:;
  1019.         if (gets (buf) == NULL) {
  1020.             clearerr (stdin);
  1021.             ps_print (ps,"(exit)\n");
  1022.             return result;
  1023.         }
  1024.  
  1025.         if ((buf[0] == NULL) 
  1026.             || (strlen(buf) != 1)
  1027.             || ((buf[0] != 'y') && (buf[0] != 'n'))) {
  1028.                 ps_print (ps,"Please type 'y' or 'n': ");
  1029.                 (void) ps_flush (ps);
  1030.                 goto again;
  1031.             }
  1032.  
  1033.         if (buf[0] == 'y') {
  1034.             newdns = dn_seq_alloc();
  1035.             newdns->dns_next = result;
  1036.             newdns->dns_dn = dn_cpy (dns->dns_dn);
  1037.             result = newdns;
  1038.             dns = dns->dns_next;
  1039.         } else {
  1040.             DNS tmp;
  1041.             tmp = dns;
  1042.             dns = dns->dns_next;
  1043.             tmp->dns_next = NULLDNS;
  1044.             dn_seq_free (tmp);
  1045.         }
  1046.     }
  1047.     ps_free (ps);
  1048.     return result;
  1049. }
  1050.  
  1051. DN dl_str2ufn (ufn)
  1052. char * ufn;
  1053. {
  1054. DNS dns = NULLDNS;
  1055. int n;
  1056. char * v[20];
  1057. PS    ps;
  1058. extern char ufn_notify;
  1059. extern int print_parse_errors, parse_status;
  1060. static envlist el = NULLEL;
  1061. DN dn;
  1062. char * ptr;
  1063. int old;
  1064.  
  1065.     ptr = strdup (ufn);
  1066.  
  1067.     if ((ps = ps_alloc (std_open)) == NULLPS) {
  1068.           (void) fprintf (stderr,"Can't set up output (7)\n");
  1069.           return NULLDN;
  1070.     }
  1071.     if (std_setup (ps, stdout) == NOTOK) {
  1072.           (void) fprintf (stderr,"Can't set up output (8)\n");
  1073.           return NULLDN;
  1074.     }
  1075.  
  1076.     if (index (ptr,'@') != NULLCP) {
  1077.         /* DN or 822 address */
  1078.  
  1079.         old = print_parse_errors;
  1080.         print_parse_errors = FALSE;
  1081.  
  1082.         if ((dn = str2dn (ptr)) != NULLDN) {
  1083.             free (ptr);
  1084.             print_parse_errors = old;
  1085.             return dn;
  1086.         }
  1087.  
  1088.         parse_status--;        /* ignore error */
  1089.         print_parse_errors = old;
  1090.  
  1091.         if ((dn = mail2dn (ps, ufn)) != NULLDN) {
  1092.             free (ptr);    
  1093.             return dn;
  1094.         }
  1095.     }
  1096.     free (ptr);
  1097.  
  1098.     if (el == NULLEL) {
  1099.         ufn_notify = TRUE;
  1100.         if ((el = read_envlist ()) == NULLEL) {
  1101.               (void) fprintf (stderr,"Can't read environment\n");
  1102.               return NULLDN;
  1103.         }
  1104.     }
  1105.  
  1106.  
  1107.     if ((n = sstr2arg (ufn,20,v,",\n")) == NOTOK) {
  1108.         (void) fprintf (stderr, "Can't parse input !!!\n");
  1109.         return NULLDN;
  1110.     }
  1111.  
  1112.     ps_print (ps,"Searching...\n");
  1113.  
  1114.     if ( ! ufn_match (n,v,dl_interact,&dns,el)) {
  1115.         (void) fprintf (stderr, "Try again later !!!\n");
  1116.         return NULLDN;
  1117.     } else {
  1118.         if (dns == NULLDNS) {
  1119.             (void) fprintf (stderr, "Nothing matched\n");
  1120.             return NULLDN;
  1121.         } else if (dns->dns_next == NULLDNS) {
  1122.             return dns->dns_dn;
  1123.         } else {
  1124.             dns = dl_interact (dns,localdn,ufn);
  1125.             if (dns == NULLDNS) {
  1126.                 (void) fprintf (stderr, "Nothing matched\n");
  1127.                 return NULLDN;
  1128.             } else if (dns->dns_next == NULLDNS) {
  1129.                 return dns->dns_dn;
  1130.             } 
  1131.             ps_print (ps, "\nYou need to select one name!\n   ");
  1132.             return NULLDN;
  1133.         }
  1134.     }
  1135.     /* NOTREACHED */
  1136. }
  1137.  
  1138. ORName * ufn_orName_parse (str,thisdl)
  1139. char * str;
  1140. Attr_Sequence thisdl;
  1141. {
  1142. ORName * or, *newor;
  1143. char * ptr;
  1144. int old;
  1145. Attr_Sequence as;
  1146. OR_ptr as2or();
  1147.  
  1148.     or = (ORName *) smalloc (sizeof (ORName));
  1149.  
  1150.     if ( (ptr=index (str,'$')) == NULLCP) {
  1151.         if ((or->on_dn = dl_str2ufn (str)) == NULLDN) 
  1152.             return (NULLORName);
  1153.  
  1154.         ufn_dl = thisdl;
  1155.  
  1156.         if (dn2addr (or->on_dn, &as) == OK)
  1157.             or->on_or = as2or (as);
  1158.         else
  1159.             or->on_or = NULLOR;
  1160.  
  1161.         if (thisdl) {
  1162.             if (user_in_list(thisdl,or->on_dn))
  1163.                 return or;
  1164.  
  1165.             ORName_free (or);
  1166.             (void) fprintf (stderr,"User not in list !\n");
  1167.             return NULLORName;
  1168.         }
  1169.         return or;
  1170.     }
  1171.  
  1172.     *ptr--= 0;
  1173.     if (isspace (*ptr)) {
  1174.         *ptr = 0;
  1175.     }
  1176.     ptr++;
  1177.     ptr++;
  1178.  
  1179.     if (*str == 0)
  1180.         or->on_dn = NULLDN;
  1181.     else {
  1182.         if ((or->on_dn = dl_str2ufn (str)) == NULLDN)
  1183.             return (NULLORName);
  1184.         ufn_dl = thisdl;
  1185.     }
  1186.  
  1187.     ptr = SkipSpace(ptr);    
  1188.     if (*ptr == 0) {
  1189.         or->on_or = NULLOR;
  1190.         if (or->on_dn != NULLDN)
  1191.             if (dn2addr (or->on_dn, &as) == OK)
  1192.                 or->on_or = as2or (as);
  1193.     } else if ((or->on_or = orAddr_parse_user (ptr)) == NULLOR)
  1194.         return (NULLORName);
  1195.     
  1196.     if (thisdl) {
  1197.         if (or->on_dn && user_in_list(thisdl,or->on_dn))
  1198.             return or;
  1199.         if (or->on_or && (newor = addr_in_list(thisdl,or->on_or)))
  1200.             return newor;
  1201.  
  1202.         ORName_free (or);
  1203.         (void) fprintf (stderr,"User not in list !\n");
  1204.         return NULLORName;
  1205.     }
  1206.     return (or);
  1207. }
  1208.  
  1209. char    input[BUFSIZ];
  1210.  
  1211. static int getinput()
  1212. {
  1213.     RP_Buf    rp;
  1214.  
  1215.     (void) fflush(stdout);
  1216.     if (gets (input) == NULL) {
  1217.         clearerr(stdin);
  1218.         pps_end(NOTOK,&rp);
  1219.         return NOTOK;
  1220.     }
  1221.     compress (input, input);
  1222.     if (*input == '\0') {
  1223.         pps_end(NOTOK,&rp);
  1224.         return NOTOK;
  1225.     }
  1226.     return OK;
  1227. }
  1228.  
  1229. static int readinput()
  1230. {
  1231.     (void) fflush(stdout);
  1232.     if (gets (input) == NULL) {
  1233.         clearerr(stdin);
  1234.         return NOTOK;
  1235.     }
  1236.     compress (input, input);
  1237.     if (*input == '\0') 
  1238.         return NOTOK;
  1239.  
  1240.     return OK;
  1241. }
  1242.  
  1243. static int error_user()
  1244. {
  1245.     RP_Buf    rp;
  1246.     pps_end(NOTOK, &rp);
  1247.     return NOTOK;
  1248. }
  1249.  
  1250. static int error_pps(rp)
  1251. RP_Buf    *rp;
  1252. {
  1253.     (void) printf("pps_error: %s\n",rp->rp_line);
  1254.     (void) fflush(stdout);
  1255.     return NOTOK;
  1256. }
  1257.  
  1258. /* */
  1259.  
  1260. orname_confirm (ps,orname,remove)
  1261. PS ps;
  1262. ORName * orname;
  1263. char remove;
  1264. {
  1265.     register char   c;
  1266.  
  1267.     if (remove)
  1268.         ps_printf (ps,"Remove ");
  1269.     else
  1270.         ps_printf (ps,"Add ");
  1271.     orName_print (ps,orname,UFNOUT);
  1272.  
  1273.     ps_printf (ps," [y/n/d] ? ");
  1274.     ps_flush (ps);
  1275.  
  1276. again:;
  1277.     c = ttychar ();
  1278.  
  1279.     switch (c)
  1280.     {
  1281.     case 'Y':
  1282.     case 'y':
  1283.         (void) printf ("yes\r\n");
  1284.         (void) fflush (stdout);
  1285.         return (TRUE);
  1286.  
  1287.     case 'N':
  1288.     case 'n':
  1289.         (void) printf ("no\r\n");
  1290.         (void) fflush(stdout);
  1291.         return (FALSE);
  1292.  
  1293.     case 'D':
  1294.     case 'd':
  1295.         (void) printf ("display...\r\n");
  1296.         if (orname->on_dn) 
  1297.         dl_showentry (ps,orname->on_dn);
  1298.         else 
  1299.         orName_print (ps,orname,UFNOUT);
  1300.         if (remove)
  1301.             ps_printf (ps,"Remove [y/n] ? ");
  1302.         else
  1303.             ps_printf (ps,"Add [y/n] ? ");
  1304.         ps_flush (ps);
  1305.         goto again;
  1306.  
  1307.     default:
  1308.         (void) printf ("Type y(es), n(o) or (d)isplay ");
  1309.         (void) fflush(stdout);
  1310.         goto again;
  1311.    }
  1312. }
  1313.  
  1314. confirm (str)
  1315. char    *str;
  1316. {
  1317.     register char   c;
  1318.  
  1319.     if (str != NULL) {
  1320.         (void) printf(str);
  1321.         (void) fflush(stdout);
  1322.     }
  1323.  
  1324. again:;
  1325.  
  1326.     (void) printf (" [y/n] ");
  1327.     (void) fflush (stdout);
  1328.  
  1329.     c = ttychar ();
  1330.  
  1331.     switch (c)
  1332.     {
  1333.     case 'Y':
  1334.     case 'y':
  1335.         (void) printf ("yes\r\n");
  1336.         (void) fflush (stdout);
  1337.         return (TRUE);
  1338.  
  1339.     case 'N':
  1340.     case 'n':
  1341.         (void) printf ("no\r\n");
  1342.         (void) fflush(stdout);
  1343.         return (FALSE);
  1344.     default:
  1345.         (void) printf ("Type y or n\n");
  1346.         (void) fflush(stdout);
  1347.         goto again;
  1348.    }
  1349. }
  1350.  
  1351. ttychar ()
  1352. {
  1353.     register int    c;
  1354.     char        buf[LINESIZE];
  1355.  
  1356.     (void) fflush (stdout);
  1357.     if (fgets (buf, LINESIZE,  stdin) == 0)
  1358.     clearerr(stdin);
  1359.  
  1360.     c = buf[0];
  1361.  
  1362.     c = toascii (c);    /* get rid of high bit */
  1363.  
  1364.     if (c == '\r')
  1365.     c = '\n';
  1366.  
  1367.     return (c);
  1368. }
  1369.  
  1370. dl_create_dsa (ps)
  1371. PS ps;
  1372. {
  1373. DN dn;
  1374. int  res;
  1375. char *listname;
  1376. char *description;
  1377. DN owner;
  1378.  
  1379.     (void) printf("\nName of new list -> ");
  1380.     if (readinput() == NOTOK)
  1381.         return NOTOK;
  1382.  
  1383.     if ((res = str2dl (input,localdn,&dn)) != NOTOK) {
  1384.         if (res == OK) {
  1385.             (void) printf("'%s' list already exists...\n",input);
  1386.             do_list (dn,input);
  1387.         } else
  1388.             (void) printf("Temporary directory failure\n",input);
  1389.         dn_free (dn);
  1390.         return NOTOK;
  1391.     }
  1392.  
  1393.     listname = strdup(input);
  1394.  
  1395.     (void) printf ("Do local users '%s-request' and '%s' exist ",listname,listname);
  1396.  
  1397.     if (confirm (NULLCP) == FALSE) {
  1398.         (void) printf("You need to create some local PP mail addresses\n");
  1399.         (void) printf("(contact the postmaster if you don't know how)\n\n");
  1400.         (void) printf("You need to create an alias of the form\n");
  1401.         (void) printf("   %s-request: alias <user>\n",listname);
  1402.         (void) printf("and a user of the form\n");
  1403.         (void) printf("   %s:dirlist [<host>]\n",listname);
  1404.         (void) printf("\nThen try again!\n\n");
  1405.         return NOTOK;
  1406.     }
  1407.  
  1408.     (void) printf("\nOwner of new list -> ");
  1409.     if (readinput() == NOTOK)
  1410.         return NOTOK;
  1411.  
  1412.     if ((owner = dl_str2ufn(input)) == NULLDN) {
  1413.         (void) printf("\nInvalid Owner");
  1414.         return NOTOK;
  1415.     }
  1416.  
  1417.     (void) printf("Description of list (one line only) -> ");
  1418.     if (readinput() == NOTOK)
  1419.         return NOTOK;
  1420.     description = strdup(input);
  1421.  
  1422.     (void) printf("Creating entry for '%s-request'...\n",listname);
  1423.     (void) fflush (stdout);
  1424.     if (! add_list_request (ps, localdn, listname, owner)) {
  1425.         return NOTOK;
  1426.     }
  1427.  
  1428.     (void) printf("Creating entry for '%s'...\n",listname);
  1429.     (void) fflush (stdout);
  1430.     if (! add_new_list (ps,localdn, listname, owner, description,NULLATTR)) {
  1431.         return NOTOK;
  1432.     }
  1433.  
  1434.     (void) str2dl (listname,localdn,&dn);
  1435.     do_list (dn,listname);
  1436.  
  1437.     return OK;
  1438. }
  1439.  
  1440. dl_create (ps)
  1441. PS ps;
  1442. {
  1443. RP_Buf    rp;
  1444. DN dn;
  1445. int  res;
  1446. char *get_spostmaster();
  1447.  
  1448.     postmaster = get_spostmaster();
  1449.  
  1450.     if (manager_mode) 
  1451.         return dl_create_dsa(ps);
  1452.  
  1453.     (void) printf("Please wait...");
  1454.     (void) fflush(stdout);
  1455.     
  1456.     if (pps_1adr("Directory based distribution list creation request",
  1457.              postmaster,
  1458.              &rp) != OK)
  1459.         return error_pps(&rp);
  1460.  
  1461.     (void) printf("\nName of new list -> ");
  1462.     if (getinput() == NOTOK)
  1463.         return error_user();
  1464.  
  1465.     if ((res = str2dl (input,localdn,&dn)) != NOTOK) {
  1466.         dn_free (dn);
  1467.         if (res == OK)
  1468.             (void) printf("'%s' list already exists\n",input);
  1469.         else
  1470.             (void) printf("Temporary directory failure\n",input);
  1471.         return error_user();
  1472.     }
  1473.  
  1474.     if (pps_txt("\nPlease create a directory based mail list:\n",&rp) != OK)
  1475.         return error_pps(&rp);
  1476.     if (pps_txt("\n   cn= ",&rp) != OK)
  1477.         return error_pps(&rp);
  1478.     if (pps_txt(input,&rp) != OK)
  1479.         return error_pps(&rp);
  1480.  
  1481.     if (pps_txt("\n   Owner= ",&rp) != OK)
  1482.         return error_pps(&rp);
  1483.     if (pps_txt(dn2str(user),&rp) != OK)
  1484.         return error_pps(&rp);
  1485.  
  1486.     (void) printf("Description of list (one line only) -> ");
  1487.     if (getinput() == NOTOK)
  1488.         return error_user();
  1489.     if (pps_txt("\n   Description= ",&rp) != OK)
  1490.         return error_pps(&rp);
  1491.     if (pps_txt(input,&rp) != OK)
  1492.         return error_pps(&rp);
  1493.  
  1494.  
  1495.     if (pps_txt("\n\n(You can use the \"dl -m\" command to do this!)\n",&rp) != OK)
  1496.         return error_pps(&rp);
  1497.  
  1498.     if (confirm ("Do you want to pass this request on to the postmaster ?") == FALSE) {
  1499.         pps_end(NOTOK,&rp);
  1500.         return 0;
  1501.     }
  1502.  
  1503.     (void) printf("Sending...");
  1504.     (void) fflush(stdout);
  1505.     if (pps_txt("\n(auto-mailing from the 'dl' tool)\n",&rp) != OK)
  1506.         return error_pps(&rp);
  1507.     if (pps_end(OK,&rp) != OK)
  1508.         return error_pps(&rp);
  1509.  
  1510.     (void) printf ("\nYour request has been passed to an administrator\n");
  1511.     (void) printf ("You will be notified in a short time when the list has been created\n");
  1512.     (void) printf ("You can then use this program to enter names into the list\n\n");
  1513.     (void) fflush (stdout);
  1514.     return 0;
  1515. }
  1516.  
  1517. dl_upgrade_dsa (ps,list,listname)
  1518. PS ps;
  1519. dl    *list;
  1520. char * listname;
  1521. {
  1522. RP_Buf    rp;
  1523. DN dn;
  1524. int  res;
  1525. char *description;
  1526. DN owner;
  1527. Attr_Sequence nas, members = NULLATTR;
  1528. Attr_Sequence mail2member ();
  1529. Name * dlm;
  1530.  
  1531.     if ((res = str2dl (listname,localdn,&dn)) != NOTOK) {
  1532.         if (res == OK) {
  1533.             (void) printf("'%s' list already exists...\n",input);
  1534.             do_list (dn,listname);
  1535.         } else
  1536.             (void) printf("Temporary directory failure\n",input);
  1537.         dn_free (dn);
  1538.         return NOTOK;
  1539.     }
  1540.  
  1541.     if ((owner = mail2dn (ps, list->dl_moderator)) == NULLDN) {
  1542.         (void) printf("\nInvalid Owner");
  1543.         return NOTOK;
  1544.     }
  1545.  
  1546.     description = list->dl_desc;
  1547.  
  1548.     for (dlm = list -> dl_list; dlm != NULL; dlm = dlm -> next) {
  1549.         if ((nas = mail2member (ps, dlm->name)) == NULLATTR) {
  1550.             (void) printf("\naddress failed '%s'",dlm->name);
  1551.             return NOTOK;
  1552.         }
  1553.         members = as_merge (members, nas);
  1554.     }
  1555.  
  1556.     (void) printf("Creating entry for '%s-request'...\n",listname);
  1557.     (void) fflush (stdout);
  1558.     if (! add_list_request (ps, localdn, listname, owner)) {
  1559.         return NOTOK;
  1560.     }
  1561.  
  1562.     (void) printf("Creating entry for '%s'...\n",listname);
  1563.     (void) fflush (stdout);
  1564.     if (! add_new_list (ps,localdn, listname, owner, description,members)) {
  1565.         return NOTOK;
  1566.     }
  1567.  
  1568.     (void) printf("Directory entries created.\n\n");
  1569.  
  1570.     (void) printf("WARNING: the address to DN mapping is experimental,\n");
  1571.     (void) printf("you should check the members of the list carefully\n\n");
  1572.  
  1573.     (void) printf("You need to modify the PP tables form\n");
  1574.     (void) printf("   %s:list [<host>]\nto\n",listname);
  1575.     (void) printf("   %s:dirlist [<host>]\n",listname);
  1576.  
  1577.     if (confirm ("Do you want to pass a request on to the postmaster ?") == FALSE) {
  1578.         (void) str2dl (listname,localdn,&dn);
  1579.         do_list (dn,listname);
  1580.         return OK;
  1581.     }
  1582.  
  1583.     (void) printf("Sending...");
  1584.     (void) fflush(stdout);
  1585.  
  1586.     if (pps_1adr("Directory based distribution list upgrade request",
  1587.              postmaster,
  1588.              &rp) != OK)
  1589.         return error_pps(&rp);
  1590.  
  1591.     if (pps_txt("\nPlease change the PP table entry for the list\n'",&rp) != OK)
  1592.         return error_pps(&rp);
  1593.     if (pps_txt(listname,&rp) != OK)
  1594.         return error_pps(&rp);
  1595.     if (pps_txt("' from 'list' to 'dirlist'\n",&rp) != OK)
  1596.         return error_pps(&rp);
  1597.  
  1598.     if (pps_txt("\n(auto-mailing from the 'dl' tool)\n",&rp) != OK)
  1599.         return error_pps(&rp);
  1600.     if (pps_end(OK,&rp) != OK)
  1601.         return error_pps(&rp);
  1602.  
  1603.     (void) str2dl (listname,localdn,&dn);
  1604.     do_list (dn,listname);
  1605.     return OK;
  1606. }
  1607.  
  1608. dl_upgrade (ps)
  1609. PS ps;
  1610. {
  1611. dl    *list;
  1612. RP_Buf    rp;
  1613. DN dn;
  1614. int  res;
  1615. char *get_spostmaster();
  1616.  
  1617.     postmaster = get_spostmaster();
  1618.  
  1619.     (void) printf("\nName of list to upgrade -> ");
  1620.     if (readinput() == NOTOK)
  1621.         return NOTOK;
  1622.  
  1623.     switch (tb_getdl (input, &list, OK)) {
  1624.         case OK:
  1625.         break;
  1626.         case DONE:
  1627.         if (list != NULL)
  1628.             dl_free(list);
  1629.         (void) printf ("Temporary failure to expand list");
  1630.         return NOTOK;
  1631.         default:
  1632.         if (list != NULL)
  1633.             dl_free(list);
  1634.         (void) printf ("Failed to expand list");
  1635.         return NOTOK;
  1636.     } 
  1637.  
  1638.     if (manager_mode) 
  1639.         return dl_upgrade_dsa(ps,list,input);
  1640.     
  1641.     (void) printf("Please wait ...");
  1642.     (void) fflush(stdout);
  1643.     
  1644.     if (pps_1adr("Directory based distribution list upgrade request",
  1645.              postmaster,
  1646.              &rp) != OK)
  1647.         return error_pps(&rp);
  1648.  
  1649.     if ((res = str2dl (input,localdn,&dn)) != NOTOK) {
  1650.         dn_free (dn);
  1651.         if (res == OK)
  1652.             (void) printf("'%s' list already exists\n",input);
  1653.         else
  1654.             (void) printf("Temporary directory failure\n",input);
  1655.         return error_user();
  1656.     }
  1657.  
  1658.     if (pps_txt("\nPlease convert the file based mail list\n   ",&rp) != OK)
  1659.         return error_pps(&rp);
  1660.     if (pps_txt(input,&rp) != OK)
  1661.         return error_pps(&rp);
  1662.     if (pps_txt("\ninto a directory based mail list\n",&rp) != OK)
  1663.         return error_pps(&rp);
  1664.     if (pps_txt("(You can do this using the 'dl' program)\n",&rp) != OK)
  1665.         return error_pps(&rp);
  1666.  
  1667.     (void) printf("\nDo you want to pass this request on to the postmaster ?");
  1668.     if (confirm (NULLCP) == FALSE) {
  1669.         pps_end(NOTOK,&rp);
  1670.         return 0;
  1671.     }
  1672.  
  1673.     (void) printf("Sending...");
  1674.     (void) fflush(stdout);
  1675.  
  1676.     if (pps_txt("\n(auto-mailing from the 'dl' tool)\n",&rp) != OK)
  1677.         return error_pps(&rp);
  1678.     if (pps_end(OK,&rp) != OK)
  1679.         return error_pps(&rp);
  1680.  
  1681.     (void) printf ("\nYour request has been passed to an administrator\n");
  1682.     (void) printf ("You will be notified in a short time when the list has been converted\n");
  1683.     (void) printf ("You can then use this program to enter names into the list\n\n");
  1684.     (void) fflush (stdout);
  1685.     return 0;
  1686. }
  1687.  
  1688.  
  1689. mail_manager (ps,dn,remove,as,dn_dl)
  1690. PS ps;
  1691. DN dn;
  1692. char remove;
  1693. Attr_Sequence as;
  1694. DN dn_dl;
  1695. {
  1696. DN manager, get_manager_dn();
  1697. DN nice_manager;
  1698. RP_Buf    rp;
  1699. Attr_Sequence das;
  1700. OR_ptr or,as2or ();
  1701. char man_buf [LINESIZE];
  1702.  
  1703.     if (remove)
  1704.         ps_print (ps,"\nSorry, you can't remove youself from the list.\n");
  1705.     else    
  1706.         ps_print (ps,"\nSorry, you can't add youself to the list.\n");
  1707.  
  1708.     if ((manager = get_manager_dn(as,FALSE)) == NULLDN)
  1709.         return NOTOK;
  1710.     if ((nice_manager = get_manager_dn(as,TRUE)) == NULLDN)
  1711.         return NOTOK;
  1712.  
  1713.     if (dn2addr (manager, &das) != OK)
  1714.         return NOTOK;
  1715.  
  1716.     if ((or = as2or (das)) == NULLOR)
  1717.         return NOTOK;
  1718.  
  1719.     or_or2rfc (or,man_buf);
  1720.  
  1721.     /* Could be neat - and check the submit permissions to make sure 
  1722.      * the user is allowed on the list ! 
  1723.          */
  1724.  
  1725.     ps_print (ps, "Do you want to mail a request to the Manager,\n");
  1726.     ufn_dn_print (ps,nice_manager,TRUE);
  1727.     ps_print (ps, " ?");
  1728.     (void) ps_flush (ps);
  1729.  
  1730.     if (! confirm (NULLCP)) 
  1731.         return NOTOK;
  1732.  
  1733.     (void) printf("Please wait...\n");
  1734.     (void) fflush(stdout);
  1735.     
  1736.     if (pps_1adr("Directory based distribution list modification request",
  1737.              man_buf,
  1738.              &rp) != OK)
  1739.         return error_pps(&rp);
  1740.  
  1741.     if (remove) {
  1742.         if (pps_txt("\nPlease remove\n   ",&rp) != OK)
  1743.             return error_pps(&rp);
  1744.     } else {
  1745.         if (pps_txt("\nPlease add\n   ",&rp) != OK)
  1746.             return error_pps(&rp);
  1747.     }
  1748.  
  1749.     if (pps_txt(dn2ufn(dn,FALSE),&rp) != OK)
  1750.         return error_pps(&rp);
  1751.  
  1752.     if (remove) {
  1753.         if (pps_txt("\nfrom the list\n   ",&rp) != OK)
  1754.             return error_pps(&rp);
  1755.     } else {
  1756.         if (pps_txt("\nto the list\n   ",&rp) != OK)
  1757.             return error_pps(&rp);
  1758.     }
  1759.  
  1760.     if (pps_txt(dn2ufn(dn_dl,FALSE),&rp) != OK)
  1761.         return error_pps(&rp);
  1762.  
  1763.     if (pps_txt(".\n(auto-mailing from the 'dl' tool)\n",&rp) != OK)
  1764.         return error_pps(&rp);
  1765.     if (pps_end(OK,&rp) != OK)
  1766.         return error_pps(&rp);
  1767.  
  1768.     (void) printf ("Your request has been passed to the manager.\n");
  1769.     (void) fflush (stdout);
  1770.  
  1771.     return 0;
  1772.  
  1773. }
  1774.  
  1775. message2manager (dn_dl,message)
  1776. DN dn_dl;
  1777. char * message;
  1778. {
  1779. DN manager, get_manager_dn();
  1780. RP_Buf    rp;
  1781. Attr_Sequence as;
  1782. Attr_Sequence das;
  1783. OR_ptr or,as2or ();
  1784. char subject [LINESIZE];
  1785. char man_buf [LINESIZE];
  1786.  
  1787.     switch (dir_getdl_aux (dn_dl, &as)) {
  1788.         case OK:
  1789.         break;
  1790.         default:
  1791.         return NOTOK;
  1792.     }
  1793.  
  1794.     if ((manager = get_manager_dn(as,FALSE)) == NULLDN)
  1795.         return NOTOK;
  1796.  
  1797.     if (dn2addr (manager, &das) != OK)
  1798.         return NOTOK;
  1799.  
  1800.     if ((or = as2or (das)) == NULLOR)
  1801.         return NOTOK;
  1802.  
  1803.     or_or2rfc (or,man_buf);
  1804.  
  1805.     sprintf (subject,"Error in mailing list '%s'",dn2ufn(dn_dl,FALSE));
  1806.     if (pps_1adr(subject, man_buf, &rp) != OK)
  1807.         return error_pps(&rp);
  1808.  
  1809.     if (pps_txt(message,&rp) != OK)
  1810.         return error_pps(&rp);
  1811.  
  1812.     if (pps_txt("\n(auto-mailing from the 'dl' tool)\n",&rp) != OK)
  1813.         return error_pps(&rp);
  1814.     if (pps_end(OK,&rp) != OK)
  1815.         return error_pps(&rp);
  1816.  
  1817.     return 0;
  1818.  
  1819. }
  1820.  
  1821. modify_dl_attrs (ps,dn_dl,as)
  1822. PS ps;
  1823. DN dn_dl;
  1824. Attr_Sequence as;
  1825. {
  1826. Attr_Sequence tmp,ntmp;
  1827. DN dnm, ndnm, get_manager_dn();
  1828. char buffer [LINESIZE];
  1829.  
  1830.     if (( dnm = get_manager_dn(as,TRUE)) == NULLDN) 
  1831.         ps_print (ps,"Entry has no Owner !!!\n");
  1832.     else {
  1833.         ps_print (ps,"Owner: ");
  1834.         ufn_dn_print (ps,dnm,TRUE);
  1835.  
  1836. retry_manager:;
  1837.            ps_print (ps,"\nEnter new name ('return' for no change): ");
  1838.            ps_flush (ps);
  1839.            if (readinput() == OK) {
  1840.                if ( (ndnm = dl_str2ufn (input)) == NULLDN) 
  1841.                    goto retry_manager;
  1842.  
  1843.                if (! dl_modify_owner (ps,dnm,ndnm,dn_dl,quiet))
  1844.                    return;
  1845.            }
  1846.  
  1847.            if (((tmp = as_find_type (as,at_Permit)) == NULLATTR) 
  1848.            || (tmp->attr_value == NULLAV))
  1849.                ps_print (ps,"\nEntry has no mhsDLSubmitPermissions !!!\n");
  1850.            else {
  1851.                ps_print (ps,"\nSubmit Permissions,");
  1852.                avs_seq_print (ps,tmp->attr_value, UFNOUT);
  1853.            }
  1854.     }
  1855.  
  1856. retry_permit:;
  1857.     ps_print (ps,"\nEnter new permission ('return' for no change): ");
  1858.     ps_flush (ps);
  1859.     if (readinput() == OK) {
  1860.         sprintf (buffer,"mhsDLSubmitPermissions=%s",input);
  1861.         if ( (ntmp = str2as (buffer)) == NULLATTR) 
  1862.             goto retry_permit;
  1863.  
  1864.         if (! dl_modify_attr (ps,tmp,ntmp,dn_dl,quiet))
  1865.             return;
  1866.     }
  1867.  
  1868.     if (((tmp = as_find_type (as,at_Policy)) == NULLATTR) 
  1869.         || (tmp->attr_value == NULLAV))
  1870.         ps_print (ps,"\nEntry has no dl-policy\n");
  1871.     else {
  1872.         ps_print (ps,"\nList Policy, ");
  1873.         avs_seq_print (ps,tmp->attr_value, UFNOUT);
  1874.     }
  1875.  
  1876. retry_policy:;
  1877.     ps_print (ps,"\nEnter new policy ('return' for no change): ");
  1878.     ps_flush (ps);
  1879.     if (readinput() == OK) {
  1880.         sprintf (buffer,"dl-policy=%s",input);
  1881.         if ( (ntmp = str2as (buffer)) == NULLATTR) 
  1882.             goto retry_policy;
  1883.  
  1884.         if (! dl_modify_attr (ps,tmp,ntmp,dn_dl,quiet))
  1885.             return;
  1886.     }
  1887.  
  1888.     ps_print (ps,"\nDone!");
  1889.  
  1890. }
  1891.  
  1892. #ifndef lint
  1893.  
  1894. void    advise (va_alist)
  1895. va_dcl
  1896. {
  1897.     int     code;
  1898.     va_list ap;
  1899.  
  1900.     va_start (ap);
  1901.  
  1902.     code = va_arg (ap, int);
  1903.  
  1904.     (void) _ll_log (log_dsap, code, ap);
  1905.  
  1906.     va_end (ap);
  1907. }
  1908.  
  1909. #else
  1910. /* VARARGS */
  1911.  
  1912. void    advise (code, what, fmt)
  1913. char    *what,
  1914.     *fmt;
  1915. int      code;
  1916. {
  1917.     advise (code, what, fmt);
  1918. }
  1919. #endif
  1920.